package svgedit.gui.actions;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JTextField;
import svgedit.gui.Frame;
import svgedit.gui.View;
import svgedit.svg.SVGElement;
import svgedit.svg.SVGGroup;
import svgedit.svg.SVGStylableElement;
import svgedit.svg.SVGLength;

/**
 * This is a Class listener that handles the JTextField stroke width Implements
 * {@link KeyListener}
 * 
 * @author SARJ
 */
public class SizeListener implements KeyListener
{
	private JTextField input;

	/**
	 * Constructs a new SizeListener
	 * 
	 * @param input
	 *            {@link JTextField}
	 */
	public SizeListener(JTextField input)
	{
		this.input = input;

	}

	/**
	 * Listens for KeyPresses event
	 */
	@Override
	public void keyPressed(KeyEvent arg0)
	{
	}

	/**
	 * Listens for KeyReleases Calls self.editSelection
	 */
	@Override
	public void keyReleased(KeyEvent arg0)
	{
		String width = input.getText().toString();
		// use a tighter regex then the one in SVGLength
		Pattern regex = Pattern.compile("(.[0-9]*)(em|ex|px|in|cm|mm|pt|pc|%)");
		Matcher match = regex.matcher(width);
		
		if(match.matches())
			editSelection(width);
		else
		    System.out.println("Invalid length: "+width);
		/*
		if (width.matches("(.[0-9]*)(em|ex|px|in|cm|mm|pt|pc|%)"));
		{
			editSelection(width);
		}
		*/
	}

	/**
	 * Listens for keyTyped event
	 */
	@Override
	public void keyTyped(KeyEvent arg0)
	{
	}

	/**
	 * Iterates over the selection Calling the appropriate method depending on
	 * the SVGElement type Possible elements are: {@link SVGGroup}, @{link
	 * SVGStylableElement}
	 * 
	 * @param newWidth
	 */
	private void editSelection(String newWidth)
	{
		View view = Frame.getFrame().getView();

		// iterate over the selection
		for (SVGElement e : view.getSelected())
		{
			if (e instanceof SVGStylableElement)
				changeStroke(e, newWidth, view);

			if (e instanceof SVGGroup)
				iterateGroup((SVGGroup) e, newWidth, view);
		}
	}

	/**
	 * 
	 * @param e
	 *            - the SVGElement to be changed {@link SVGElement}
	 * @param width
	 *            - The new stroke with to be applied
	 * @param v
	 *            - the viewport to add too {@link View}
	 */
	private void changeStroke(SVGElement e, String width, View v)
	{

		// create a new length with the new width and set the strokeSize()
		SVGLength svglength = new SVGLength(width, Frame.getFrame().getView());
		((SVGStylableElement) e).setStrokeSize(svglength);

		v.repaint();

	}

	/**
	 * 
	 * @param g
	 *            - the group to be iterated {@link SVGGroup}
	 * @param newWidth
	 *            - the new width to be applied
	 * @param v
	 *            - the viewport to add to {@link View}
	 */
	private void iterateGroup(SVGGroup g, String newWidth, View v)
	{
		// loop over each group
		for (SVGElement e : g)
		{

			// if the element is of type styleable element, changeStroke()
			if (e instanceof SVGStylableElement)
			{
				changeStroke(e, newWidth, v);

			}
			// if there is a nested group, iterate again
			else if (e instanceof SVGGroup)
				iterateGroup((SVGGroup) g, newWidth, v);
		}
	}
}
